package com.inspur.edp.common.type.parser;

import com.inspur.edp.common.type.Type;
import com.inspur.edp.common.type.TypeRefer;
import com.inspur.edp.common.type.constant.TypeConstant;
import com.inspur.edp.common.type.cache.TypeThreadCache;

import java.util.List;

/**
 * @author lizhaorui
 * @date 2025/8/18
 * @description
 */
public class TypeCompareMgr {

    public static boolean equalOrIsInstance(TypeRefer provider, TypeRefer require) {
        if (!singleEqualOrIsInstance(provider, require)) {
            return false;
        }
        if (require.getGenericTypes() != null) {
            List<TypeRefer> ps = provider.getGenericTypes();
            List<TypeRefer> rs = require.getGenericTypes();
            if (ps != null) {
                if (rs.size() != ps.size()) {
                    return false;
                } else {
                    int index = 0;
                    for (TypeRefer psItem : ps) {
                        boolean eOrInst = singleEqualOrIsInstance(psItem, rs.get(index));
                        if (!eOrInst) {
                            return false;
                        }
                        index++;
                    }
                }
            }
        }
        return true;
    }


    public static boolean singleEqualOrIsInstance(TypeRefer provider, TypeRefer require) {
        if (isEqual(provider, require)) {
            return true;
        }
        if (isInstance(provider, require)) {
            return true;
        }
        return false;
    }

    public static boolean isEqual(TypeRefer provider, TypeRefer require) {
        if (provider.getSource().equals(require.getSource())
                && provider.getTypeId().equals(require.getTypeId())) {
            return true;
        }
        if (require.getTypeId().equals("any") &&
                require.getSource().equals(TypeConstant.DEFAULT_VALUE)) {
            return true;
        }
        if (provider.getTypeId().equals(TypeRefer.NUMBER) && require.isNumber()) {
            return true;
        }
        if (provider.isNumber() && require.getTypeId().equals(TypeRefer.NUMBER)) {
            return true;
        }
        return false;
    }

    public static boolean isInstance(TypeRefer provider, TypeRefer require) {
        Type providerType = TypeThreadCache.getType(provider);
        if (providerType.getExtendType() != null) {
            TypeRefer extendType = providerType.getExtendType();
            boolean extendEqual = isEqual(extendType, require);
            if (extendEqual) {
                return true;
            } else {
                return isInstance(extendType, require);
            }
        }
        return false;
    }


}